# 入门

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。 Node.js 使用了一个事件驱动非阻塞式 I/O 的模型,使其轻量又高效。在特定领域性能出色,比如用 Node.js 实现消息推送、状态监控等的业务功能非常合适。

传统意义上的 JavaScript 运行在浏览器上,Chrome 使用的 JavaScript 引擎是 V8,Node.js 是一个运行在服务端的框架,它的底层就使用了 V8 引擎,这样就可以使用 javascript 去编写一些服务端的程序,这样也就实现了用 javaScript 去开发服务端的功能,这样做的好处就是前端和后端都采用 javascript,即开发一份 js 程序即可以运行在前端也可以运行的服务端,这样比一个应用使用多种语言在开发效率上要高。

# 使用 NVM 安装 Node

Node.js 官网下载所属平台的安装包或二进制文件,安装后在命令行输入node -v查看版本

有时需要切换版本,推荐使用nvm安装 Node,Github

# 使用 Oh My Zsh 安装 NVM

git clone https://github.com/lukechilds/zsh-nvm ~/.oh-my-zsh/custom/plugins/zsh-nvm

Then load as a plugin in your .zshrc

plugins+=(zsh-nvm)

刷新.zshrc

source ~/.zshrc

# 使用 install script 安装 NVM

To install or update nvm, you should run the install script. To do that, you may either download and run the script manually, or use the following cURL or Wget command:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash

# 使用 NVM 安装 Node

To download, compile, and install the latest release of node, do this:

nvm install node # "node" is an alias for the latest version

列出可以安装的版本🔥

# 主要的版本
nvm ls
# 远程所有的可用版本
nvm ls-remote

安装LTS版本 🔥

nvm install --lts

安装特定版本 🔥

nvm install 8.17.0 # or 10.10.0, 8.9.1, etc

切换版本

nvm use v12.18.0

其他使用方法后续再添加

# NPM

NPM 全称 Node Package Manager,他是 Node 包管理和分发工具。其实我们可以把 NPM 理解为前端的 Maven。我们通过 NPM 可以很方便地下载 js 库,管理前端工程。 Node.js 已经集成了 npm 工具,npm -v可查看当前 npm 版本

# NRM

用于切换镜像

# 安装 nrm
npm install -g nrm
# 查看可用镜像
nrm ls
# 切换镜像
nrm use <xxx>

# CNPM

有时我们使用 npm 下载资源会很慢,所以我们可以安装一个 cnmp(淘宝镜像)来加快下载速度。输入如下命令:

npm install -g cnpm --registry=https://registry.npm.taobao.org

安装后使用.\cnpm -v查看 cnpm 版本(在npm_modules目录下执行)

安装 nrm.\cnpm install -g nrm(在npm_modules目录下执行)

.\nrm ls查看镜像后,使用nrm use XXX切换镜像(在npm_modules目录下执行)

配置环境变量后即可在任意目录下执行

  • 配置NODE_HOME = C:\Program Files\nodejs
  • Path 中配置%NODE_HOME%;%NODE_HOME%\npm_modules;

# 初始化工程

init命令是工程初始化命令。建立一个空文件夹,在命令提示符进入该文件夹执行命令初始化npm init

按照提示输入相关信息,如果是用默认值则直接回车即可。

  • name: 项目名称
  • version: 项目版本号
  • description: 项目描述
  • keywords: {Array}关键词,便于用户搜索到我们的项目

最后会生成package.json文件,这个是包的配置文件,相当于 maven 的pom.xml我们之后也可以根据需要进行修改。

# 本地安装

install 命令用于安装某个模块,如果我们想安装express模块(node 的 web 框架),输出命令如下npm install express

出现黄色的是警告信息,可以忽略,请放心,你已经成功执行了该命令。

在该目录下已经出现了一个node_modules文件夹 和package-lock.json

node_modules文件夹用于存放下载的 js 库(相当于 maven 的本地仓库)

package-lock.json是当 node_modulespackage.json 发生变化时自动生成的文件。这个文件主要功能是确定当前安装的包的依赖,以便后续重新安装的时候生成相同的依赖,而忽略项目开发过程中有些依赖已经发生的更新。

我们再打开 package.json 文件,发现刚才下载的 express 已经添加到依赖列表中了.

关于版本号定义:

  • 指定版本:比如1.2.2,遵循“大版本.次要版本.小版本”的格式规定,安装时只安装指定版本。
  • 波浪号(tilde)+指定版本:比如~1.2.2,表示安装1.2.x的最新版本(不低于1.2.2),但是不安装 1.3.x,也就是说安装时不改变大版本号和次要版本号
  • 插入号(caret)+指定版本:比如^1.2.2,表示安装1.x.x的最新版本(不低于 1.2.2),但是不安装 2.x.x,也就是说安装时不改变大版本号。需要注意的是,如果大版本号为 0,则插入号的行为与波浪号相同,这是因为此时处于开发阶段,即使是次要版本号变动,也可能带来程序的不兼容。
  • latest:安装最新版本。

# 全局安装

刚才我们使用的是本地安装,会将 js 库安装在当前目录,而使用全局安装会将库安装到你的全局目录下。

如果你不知道你的全局目录在哪里,执行命令npm config lsnpm root -g

我的全局目录在C:/用户/[用户名]/AppData/Roming/npm/node_meodules。为了方便对依赖包管理,我们将管理包的路径设置在单独的地方,本教程将安装目录设置在 node.js 的目录下,创建npm_modulesnpm_cache,执行下边的命令:

npm config set prefix "C:\Develop\nodejs\npm_modules"
npm config set cache "C:\Develop\nodejs\npm_cache"

比如我们全局安装 jquery, 输入以下命令npm install jquery -g

# 批量下载

我们从网上下载某些代码,发现只有package.json,没有node_modules文件夹,这时我们需要通过命令重新下载这些 js 库

进入目录(package.json 所在的目录)输入命令npm install,此时,npm 会自动下载package.json中依赖的 js 库.

# 运行工程

如果我们想运行某个工程,则使用 run 命令

如果package.json中定义的脚本如下

  • dev是开发阶段测试运行
  • build是构建编译工程
  • lint 是运行 js 代码检测

我们现在来试一下运行 dev,命令行输入npm run dev

# 编译工程

我们接下来,测试一个代码的编译,编译后我们就可以将工程部署到 nginx 中啦~

编译后的代码会放在dist文件夹中,首先我们先删除 dist 文件夹中的文件,进入命令提示符输入命令npm run build

生成后我们会发现只有一个静态页面,和一个static文件夹

这种工程我们称之为单页 Web 应用(single page web application,SPA),就是只有一张 Web 页面的应用,是加载单个 HTML 页面并在用户与应用程序交互时动态更新该页面的 Web 应用程序。

这里其实是调用了 webpack 来实现打包的,关于 webpack 我们后续的章节进行介绍

# 快速入门

# 控制台输出

我们现在做个最简单的小例子,演示如何在控制台输出,创建文本文件 demo1.js,代码内容

var a = 1;
var b = 2;
console.log(a + b);

我们在命令提示符下输入命令

node demo1.js

# 使用函数

创建文本文件 demo2.js

var c = add(100, 200);
console.log(c);
function add(a, b) {
  return a + b;
}

命令提示符输入命令。运行后看到输出结果为 300

node demo2.js

# 模块化编程

创建文本文件 demo3_1.js

exports.add = function(a, b) {
  return a + b;
};

创建文本文件 demo3_2.js

var demo = require("./demo3_1"); //ES5的语法
console.log(demo.add(400, 600));

我们在命令提示符下输入命令。结果为 1000

node demo3_2.js

# 创建 web 服务器

创建文本文件 demo4.js

var http = require("http");
http
  .createServer(function(request, response) {
    // 发送 HTTP 头部
    // HTTP 状态值: 200 : OK
    // 内容类型: text/plain
    response.writeHead(200, { "Content-Type": "text/plain" });
    // 发送响应数据 "Hello World"
    response.end("Hello World\n");
  })
  .listen(8888);
// 终端打印如下信息
console.log("Server running at http://127.0.0.1:8888/");

http为 node 内置的 web 模块

我们在命令提示符下输入命令

node demo4.js

服务启动后,我们打开浏览器,输入网址http://localhost:8888/

即可看到网页输出结果 Hello World。Ctrl+c 终止运行。

# 理解服务端渲染

我们创建 demo5.js  ,将上边的例子写成循环的形式

var http = require("http");
http
  .createServer(function(request, response) {
    // 发送 HTTP 头部
    // HTTP 状态值: 200 : OK
    // 内容类型: text/plain
    response.writeHead(200, { "Content-Type": "text/plain" });
    // 发送响应数据 "Hello World"
    for (var i = 0; i < 10; i++) {
      response.write("Hello World\n"); //write和end区别
    }
    response.end("");
  })
  .listen(8888);
// 终端打印如下信息
console.log("Server running at http://127.0.0.1:8888/");

我们在命令提示符下输入命令启动服务

node demo5.js

浏览器地址栏输入http://127.0.0.1:8888即可看到查询结果。

我们右键“查看源代码”发现,并没有我们写的 for 循环语句,而是直接的 10 条 Hello World ,这就说明这个循环是在服务端完成的,而非浏览器(客户端)来完成。这与我们原来的 JSP 很是相似。

# 接收参数

创建 demo6.js

var http = require("http");
var url = require("url");
http
  .createServer(function(request, response) {
    response.writeHead(200, { "Content-Type": "text/plain" });
    // 解析 url 参数
    var params = url.parse(request.url, true).query;
    response.write("name:" + params.name);
    response.write("\n");
    response.end();
  })
  .listen(8888);
console.log("Server running at http://127.0.0.1:8888/");

我们在命令提示符下输入命令

node demo6.js

在浏览器测试结果